import java.util.Arrays;

public class Test {
    public static void func() {
        int[] array1 = new int[3];
        array1[0] = 10;
        array1[1] = 20;
        array1[2] = 30;

        int[] array2 = new int[]{1,2,3,4,5};
        array2[0] = 100;
        array2[1] = 200;

        array1 = array2;    //这里是把array2引用所指向对象的地址赋值给了array1引用变量
        array1[2] = 300;    //array1和array2两个引用同时指向同一个对象
        array1[3] = 400;    //注意:array1原先所指向的对象由于没有引用指向它,所以JVM会进行回收，释放空间
        array1[4] = 500;

        //func方法执行完毕，此时array1,array2会被销毁回收，此时该对象如果再没有指向它的引用，也会被JVM回收
    }
    //数组做参数
    public static void func1(int[] array){
        array = new int[10];    //这个函数只是改变了形参引用的指向，对实参引用并不造成影响
    }                           //Java中并不是传引用就会一定影响实参，要看你用引用干了什么
    public static void func2(int[] array) {
        array[0] = 99;          //这个函数会改变实参引用指向对象的值
    }
    //数组做返回值
    public static int[] func3() {
        return new int[]{1,2,3,4,5};          //这个函数会返回这个对象的地址
    }
    //自己写的toString
    public static String myToString(int[] array) {
        String ret = "[";
        for (int i = 0; i < array.length; i++) {
            ret += array[i];
            if(i != array.length - 1) {
                ret += ",";
            }
        }
        ret += "]";
        return ret;
    }

    public static void main(String[] args) {
        int[] array1 = null; //表示array这个引用不指向任何对象
        //System.out.println(array.length);//null表示一个无效内存，不能对这个内存进行任何的读写操作
                                           //一旦进行读写操作，就会抛出空指针异常（NullPointerException）
        //一旦遇见空指针异常，就要定位，去看看哪个引用是空的

        //Arrays类-->Java中专门用来操作数组的工具类
        int[] array2 = new int[]{1,2,3,4,5};
        String s = Arrays.toString(array2);     //Arrays.toString()把数组的内容以字符串的形式返回
        System.out.println(s);
        //自己实现一个toString
        String ret = myToString(array2);
        System.out.println(ret);
        //数组拷贝-->1.for循环实现--Java中定义数组，其中的[]中可以是变量，极大方便我们用for循环去实现拷贝
        //       -->2.借助Arrays工具类实现--Arrays.copyOf(T[],int); T表示泛式
        //       -->3.借助System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
        int[] copy = Arrays.copyOf(array2,array2.length);   //如果第二个参数大于拷贝数组的长度，则会扩容，不会报错
        System.out.println(Arrays.toString(copy));          //多的元素一般为默认值
        int[] copy1 = new int[array2.length];
        System.arraycopy(array2,0,copy1,0,array2.length); //arraycopy是本地函数，底层用C/C++实现
        System.out.println(Arrays.toString(copy1));           //如果拷贝长度length大于两个数组的长度，会报越界异常
        //Arrays.copyOfRange(T[],int from,int to)-->拷贝下标为[from,to)范围的数组部分,如果第三个参数大于拷贝数组的长度
        //                                          则会扩容，不会报错,多的元素一般为默认值
        copy = Arrays.copyOfRange(array2,1,13);
        System.out.println(Arrays.toString(copy));
        //Arrays工具类提供Arrays.sort(T[])给数组进行排序
        int[] array3 = new int[]{1,3,6,2,4};
        System.out.println("排序前：" + Arrays.toString(array3));
        Arrays.sort(array3);
        System.out.println("排序后：" + Arrays.toString(array3));

        //二维数组-->定义方式
        int[][] arr1 = {{1,2,3},{4,5,6}};
        int[][] arr2 = new int[][]{{1,2,3},{4,5,6}};
        int[][] arr3 = new int[2][3];   //元素默认值为0

        //arr1.length是行数，arr1[0].length是列数
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr1[0].length; j++) {
                System.out.print(arr1[i][j] + " ");
            }
            System.out.println();
        }
        //Arrays提供打印二维数组的方法-->deepToString()
        //如果用toString()打印二维数组，只会打印出二维数组本质(一维数组)中存储的一维数组的地址
        System.out.println(Arrays.toString(arr1));      //打印地址
        System.out.println(Arrays.deepToString(arr1));  //打印二维数组的字符串形式
        //Java中，提供不规则二维数组,C/C++不提供不规则二维数组，要实现类似功能，要自己定义类或结构体
        //Java中的二维数组的定义(不可省略行数,可省略列数)，与C/C++中的二维数组相反(可省略行数,不可省略列数)
        int[][] arr4 = new int[2][];
        arr4[0] = new int[]{1,2,3};
        arr4[1] = new int[]{4,5,6,7,8,9};
        System.out.println(Arrays.deepToString(arr4));
        //如果在省略列数的情况下，不赋具体值，则二维数组的本质(一维数组)中存储的是null，所以此时访问arr5[0].length会报空指针异常
        int[][] arr5 = new int[2][];
        System.out.println(arr5.length);        //输出2，二维数组的本质(一维数组)只存储2个元素(2个一维数组的地址)
        System.out.println(arr5[0].length);     //会报空指针异常
    }
}
